package com.gelian.geliansdk.control;

import android.annotation.SuppressLint;

import com.gelian.geliansdk.GlEngine;
import com.gelian.geliansdk.GlResultCode;
import com.gelian.geliansdk.callback.GlCallback;
import com.gelian.geliansdk.callback.RequestDeviceValueCallback;
import com.gelian.geliansdk.listener.GlDeviceValueListener;

import org.json.JSONArray;
import org.json.JSONException;
import org.w3c.dom.NameList;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class GlTvPartnerController {
    public static final int ID_POWER_ON = 0;
    public static final int ID_ADD_TIMING = 1;
    public static final int ID_DEL_TIMING = 2;
    public static final int ID_EDIT_TIMING = 3;
    public static final int ID_IR_LEARN = 4;
    public static final int ID_DELAY_OFF = 5;
    public static final int ID_TIMINGS = 6;
    public static final int ID_DELAY_TIMING = 7;
    public static final int ID_SET_TIMESTAMP = 8;

    private static final Map<Integer, Object> CTRL_MAP = new HashMap<>();
    private static final Set<Integer> REQUEST_SET = new HashSet<>();
    public static final Map<String, GlTvPartnerValueListener> LISTENER_MAP = new HashMap<>();


    public interface GlTvPartnerValueListener {
        void power_on(Object power_on);

        void add_timing(Object add_timing);

        void del_timing(Object del_timing);

        void edit_timing(Object edit_timing);

        void ir_learn(Object ir_learn);

        void delay_off(Object delay_off);

        void timings(Object timings);

        void delay_timing(Object delay_timing);
    }

    static {
        GlEngine.setDeviceValueListener(new GlDeviceValueListener() {
            @Override
            public void done(String imei, Map<Integer, Object> map_id_value) {
                GlTvPartnerValueListener listener = LISTENER_MAP.get(imei);
                if (listener != null) {
                    Set<Integer> keySet = map_id_value.keySet();
                    for (int chrc_id : keySet) {
                        Object value = map_id_value.get(chrc_id);
                        switch (chrc_id) {
                            case ID_POWER_ON:
                                listener.power_on(value);
                                break;
                            case ID_ADD_TIMING:
                                listener.add_timing(value);
                                break;
                            case ID_DEL_TIMING:
                                listener.del_timing(value);
                                break;
                            case ID_EDIT_TIMING:
                                listener.edit_timing(value);
                                break;
                            case ID_IR_LEARN:
                                listener.ir_learn(value);
                                break;
                            case ID_DELAY_OFF:
                                listener.delay_off(value);
                                break;
                            case ID_TIMINGS:
                                listener.timings(value);
                                break;
                            case ID_DELAY_TIMING:
                                listener.delay_timing(value);
                                break;
                            case ID_SET_TIMESTAMP:
                                try {
                                    long timestamp = (long) value;
                                    if (timestamp == 0) {
                                        @SuppressLint("UseSparseArrays") HashMap<Integer, Object> map = new HashMap<>();
                                        map.put(ID_SET_TIMESTAMP, System.currentTimeMillis());
                                        GlEngine.controlDevice(imei, map, new GlCallback() {
                                            @Override
                                            public void done(int resultCode) {

                                            }
                                        });
                                    }
                                } catch (Exception ignored) {

                                }
                                break;
                        }
                    }
                }
            }
        });
    }

    public static void setValueListener(String imei, GlTvPartnerValueListener listener) {
        LISTENER_MAP.put(imei, listener);
    }


    public static void setPowerOnValue(String imei, boolean on, GlCallback callback) {
        if (callback == null) {
            return;
        }
        CTRL_MAP.clear();

        CTRL_MAP.put(GlTvPartnerController.ID_POWER_ON, on ? 1 : 0);

        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }

    public static abstract class RequestPowerOnAndTimingsAndPowerDelayCallback extends RequestDeviceValueCallback {

        public abstract void done(int resultCode, boolean power_on, int[] timings, int delay_off, int delay_timing);

        @Override
        public void done(int resultCode, HashMap<Integer, Object> var) {
            boolean power_on = false;
            int[] timings = null;
            int delay_off = 90;
            int delay_timing = 0;
            if (resultCode == GlResultCode.GL_CALLBACK_CODE_SUCCESS) {
                Object valu_powerOn = var.get(GlTvPartnerController.ID_POWER_ON);
                Object valu_delayOff = var.get(GlTvPartnerController.ID_DELAY_OFF);
                Object valu_delayTiming = var.get(GlTvPartnerController.ID_DELAY_TIMING);
                try {
                    power_on = (int) valu_powerOn == 1;
                    delay_off = (int) valu_delayOff;
                    delay_timing = (int) valu_delayTiming;
                    //                    String valu = (String) var.get(GlTvPartnerController.ID_TIMINGS);
                    //                    JSONArray jsonArray = new JSONArray(valu);
                    timings = parseTimings(var);
                } catch (Exception e) {

                }
            }
            done(resultCode, power_on, timings, delay_off, delay_timing);

        }
    }

    private static int[] parseTimings(HashMap<Integer, Object> var) throws JSONException {
        JSONArray jsonArray = (JSONArray) var.get(GlTvPartnerController.ID_TIMINGS);
        int[] timings = new int[jsonArray.length()];
        for (int i = 0; i < timings.length; i++) {
            timings[i] = jsonArray.getInt(i);
        }
        return timings;
    }


    public static void requestPowerOnAndTimingsValue(String imei, RequestPowerOnAndTimingsAndPowerDelayCallback callback) {
        if (callback == null) {
            return;
        }
        REQUEST_SET.clear();
        REQUEST_SET.add(GlTvPartnerController.ID_POWER_ON);
        REQUEST_SET.add(GlTvPartnerController.ID_TIMINGS);
        REQUEST_SET.add(GlTvPartnerController.ID_DELAY_OFF);
        REQUEST_SET.add(GlTvPartnerController.ID_DELAY_TIMING);

        GlEngine.requestDeviceValue(imei, REQUEST_SET, callback);
    }


    public static void setDelayTiming(String imei, int delayTiming, GlCallback callback) {
        if (callback == null) {
            return;
        }
        CTRL_MAP.clear();
        CTRL_MAP.put(GlTvPartnerController.ID_DELAY_TIMING, delayTiming);

        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }

    public static void setDelayOff(String imei, int delayOff, GlCallback callback) {
        if (callback == null) {
            return;
        }
        CTRL_MAP.clear();
        CTRL_MAP.put(GlTvPartnerController.ID_DELAY_OFF, delayOff);

        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }

    public static void setAddTiming(String imei, int timingTask, GlCallback callback) {
        if (callback == null) {
            return;
        }
        CTRL_MAP.clear();
        CTRL_MAP.put(GlTvPartnerController.ID_ADD_TIMING, timingTask);

        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }

    public static void setEditTiming(String imei, int timingTask, GlCallback callback) {
        if (callback == null) {
            return;
        }
        CTRL_MAP.clear();
        CTRL_MAP.put(GlTvPartnerController.ID_EDIT_TIMING, timingTask);

        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }

    public static void setIrLearn(String imei, int ir_learn, GlCallback callback) {
        if (callback == null) {
            return;
        }
        CTRL_MAP.clear();
        CTRL_MAP.put(GlTvPartnerController.ID_IR_LEARN, ir_learn);

        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }

    public static void setDelTiming(String imei, int timingTask, GlCallback callback) {
        if (callback == null) {
            return;
        }
        CTRL_MAP.clear();
        CTRL_MAP.put(GlTvPartnerController.ID_DEL_TIMING, timingTask);

        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }


    public static abstract class RequestTimingCallback extends RequestDeviceValueCallback {

        public abstract void done(int resultCode, int[] timings);

        @Override
        public void done(int resultCode, HashMap<Integer, Object> var) {
            int[] timings = null;
            if (resultCode == GlResultCode.GL_CALLBACK_CODE_SUCCESS) {
                try {
                    timings = parseTimings(var);
                } catch (Exception e) {

                }
            }
            done(resultCode, timings);
        }
    }


    public static void requestTiming(String imei, RequestTimingCallback callback) {
        if (callback == null) {
            return;
        }
        REQUEST_SET.clear();
        REQUEST_SET.add(GlTvPartnerController.ID_TIMINGS);

        GlEngine.requestDeviceValue(imei, REQUEST_SET, callback);
    }


}
